跳到主要内容

oauth 对接

申请 OAuth App

创建地址:https://github.com/settings/apps/new

授权 OAuth 应用

简单的伪代码实现

首先发起重定向,重定向到 GitHub 授权页面,同时传递一个随机字符串作为 state 参数。

import React, { useRef } from 'react';

import { customAlphabet } from 'nanoid';

const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 8);
const state = useRef(nanoid());
const clientId = 'xxxxxxxxxxxxxxxxxxxx';

const redirectUri = encodeURIComponent('https://xxxxxxxxxx.com/login');
const redirectUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&state=${state.current}&scope=user:email%20read:user`

接收 GitHub 重定向,并从查询参数中获取 code。 使用此 code 向 GitHub 请求访问令牌。(这里申请取得的是用户邮箱) 处理 GitHub 返回的响应,并将令牌保存到会话或数据库中。

import axios from 'axios';

// 假设这个函数是处理GitHub回调的API路由
export default async function handler(req, res) {
// 获取GitHub返回的授权码
const code = req.query.code;

try {
// 使用授权码获取访问令牌
const tokenResponse = await axios.post('https://github.com/login/oauth/access_token', {
client_id: process.env.GITHUB_CLIENT_ID,
client_secret: process.env.GITHUB_CLIENT_SECRET,
code: code
}, {
headers: {
accept: 'application/json'
}
});

const accessToken = tokenResponse.data.access_token;

// 使用访问令牌获取用户信息
const userResponse = await axios.get('https://api.github.com/user', {
headers: {
Authorization: `token ${accessToken}`
}
});

const userEmailResponse = await axios.get('https://api.github.com/user/emails', {
headers: {
Authorization: `token ${accessToken}`
}
});

// 用户名和邮箱地址
const username = userResponse.data.login;
const userEmails = userEmailResponse.data;
const primaryEmail = userEmails.find(email => email.primary).email;

// 响应数据
res.status(200).json({ username, primaryEmail });
} catch (error) {
// 错误处理
res.status(500).json({ message: 'Authentication failed' });
}
}

References